package com.wzdigit.wms.wms.service.core.inventory;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.wms.basic.client.response.report.InvGroupInfo;
import com.wzdigit.wms.basic.client.response.report.SaleReportInvInfo;
import com.wzdigit.wms.basic.client.response.report.SoGroupInfo;
import com.wzdigit.wms.basic.mapper.core.inventory.LotInvReportMapper;
import com.wzdigit.wms.common.entity.ExcelExportConfig;
import com.wzdigit.wms.common.utils.HttpExcel;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.request.report.SaleInvReportSearchRequest;
import com.wzdigit.wms.basic.client.response.report.SaleInvReportReponse;
import com.wzdigit.wms.basic.mapper.core.inventory.InvReprotCommonMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.SaleInvReportMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 整机外销库存报表Service
 * Created by zyf on 2021/4/22 11:39
 */
@Service
@Slf4j
public class SaleInvReportService {
    @Autowired
    private SaleInvReportMapper saleInvReportMapper;

    @Autowired
    private LotInvReportMapper lotInvReportMapper;

    //查询整机外销库存报表[复用]
    public List<SaleInvReportReponse> selectSaleInvReport(SaleInvReportSearchRequest search){
        List<SaleInvReportReponse> datas = saleInvReportMapper.selectAll(search);
        try {
            for (SaleInvReportReponse data : datas) {
                List<String> lotnos = saleInvReportMapper.selectLotno(data.getSoNo(), data.getSoItem());
                BigDecimal totalInvQtys=BigDecimal.ZERO;
                BigDecimal totalFreezeInvQtys=BigDecimal.ZERO;
                if (!CollectionUtil.isEmpty(lotnos)){

                    BigDecimal invQtys=saleInvReportMapper.selectInvQty(data,lotnos,null);
                    if (invQtys!=null) totalInvQtys=invQtys;
                    BigDecimal freezeInvQtys = saleInvReportMapper.selectInvQty(data, lotnos, 2);
                    if (freezeInvQtys!=null) totalFreezeInvQtys=freezeInvQtys;

                }
                if (data.getQty()==null) data.setQty(BigDecimal.ZERO);
                data.setInvQtys(totalInvQtys);
                data.setFreezeInvQtys(totalFreezeInvQtys);

                //根据库龄设置库龄分类
                if (data.getInvAge()!=null){
                    if (data.getInvAge()<=30L){
                        data.setInvAgeType("常规库存");
                    }else if (data.getInvAge()<=60L){
                        data.setInvAgeType("预警库存");
                    }else {
                        data.setInvAgeType("呆滞库存");
                    }
                }else {
                    data.setInvAgeType("常规库存");
                }

            }


        }catch (Exception e){
            e.printStackTrace();
        }
        return datas;
    }

    /**
     * 分页查询整机外销库存报表信息
     *
     * @param search
     * @param pager
     * @return
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PagerInfo<List<SaleInvReportReponse>> searchSaleInvReport(
            SaleInvReportSearchRequest search, Pager<?> pager) {
        Page<SaleInvReportReponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<SaleInvReportReponse> datas = this.selectSaleInvReport(search);
        PagerInfo<List<SaleInvReportReponse>> pagerInfo = new PagerInfo<>();
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);

        return pagerInfo;
    }

    /**
     * 导出整机外销库存报表信息
     *
     * @param search
     * @param servletRequest
     * @param servletResponse
     * @return
     */
    @Transactional
    public void exportSaleInvReport(
            SaleInvReportSearchRequest search,
            HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{
        ServletOutputStream out = null;
        XSSFWorkbook workbook = null;
        try {
            List<SaleInvReportReponse> resultDatas=this.exportSaleComon(search);
            List<ExcelExportConfig> configs = new ArrayList<>();
            configs.add(new ExcelExportConfig("组织", "factory", 120));
            configs.add(new ExcelExportConfig("销售订单号", "soNo", 120));
            configs.add(new ExcelExportConfig("销售订单行号", "soItem", 120));
            configs.add(new ExcelExportConfig("订单号", "po", 120));
            configs.add(new ExcelExportConfig("物料编码", "skuCode", 120));
            configs.add(new ExcelExportConfig("物料描述", "descCn", 120));
            configs.add(new ExcelExportConfig("原型机", "modelMechanic", 120));
            configs.add(new ExcelExportConfig("部门名称", "businessDept", 120));
            configs.add(new ExcelExportConfig("科室名称", "businessSection", 120));
            configs.add(new ExcelExportConfig("客户编码", "customerCode", 120));
            configs.add(new ExcelExportConfig("客户名称", "customerName", 120));
            configs.add(new ExcelExportConfig("品牌", "brand", 120));
            configs.add(new ExcelExportConfig("国家", "country", 120));
            configs.add(new ExcelExportConfig("业务员", "businessMan", 120));
            configs.add(new ExcelExportConfig("订单类型", "soType", 120));
            configs.add(new ExcelExportConfig("机型类型", "modeType", 120));
            configs.add(new ExcelExportConfig("付款方式", "payMode", 120));
            configs.add(new ExcelExportConfig("定/变频", "frequeType", 120));
            configs.add(new ExcelExportConfig("是否窗机", "isWindow", 120));
            configs.add(new ExcelExportConfig("是否散件", "isCskd", 120));
            configs.add(new ExcelExportConfig("最后入库时间", "lastStockInDate", 120));
            configs.add(new ExcelExportConfig("开工时间", "planDate", 120));
            configs.add(new ExcelExportConfig("订单数量", "qty", 120));
            configs.add(new ExcelExportConfig("未结量", "noCountQty", 120));
            configs.add(new ExcelExportConfig("库存量", "invQtys", 120));
            configs.add(new ExcelExportConfig("封位货位库存", "freezeInvQtys", 120));
            configs.add(new ExcelExportConfig("库龄", "invAge", 120));
            configs.add(new ExcelExportConfig("库龄分类", "invAgeType", 120));

            workbook = HttpExcel.newListToExcel(resultDatas, configs);
            String userAgent = servletRequest.getHeader("USER-AGENT");
            String fileName = "整机外销库存报表";
            if (userAgent.contains("Mozilla")) {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, "utf8");
            }
            servletResponse.setContentType("application/octet-stream");
            servletResponse.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".xlsx");
            servletResponse.flushBuffer();
            out = servletResponse.getOutputStream();
            workbook.write(out);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
            if(workbook != null) {
                workbook.close();
            }
        }
    }


    public List<SaleInvReportReponse> exportSaleComon(SaleInvReportSearchRequest search){
        //查询销售+订单号+批次号信息
        List<SoGroupInfo> soGroupInfos = lotInvReportMapper.selectSoGroup();
        //查询库存信息
        List<SaleReportInvInfo> invGroupInfo = saleInvReportMapper.selectSaleInvGroup();
        //查询封位库存信息
        List<SaleReportInvInfo> freezeGroupInfo = saleInvReportMapper.selectFreezeGroup();
        //分组
        Map<String, List<SoGroupInfo>> soCollect = soGroupInfos.stream().collect(Collectors.groupingBy(t ->
                t.getSoNo() + "#" + t.getSoItem()));
        Map<String, List<SaleReportInvInfo>> invCollect = invGroupInfo.stream().collect(Collectors.groupingBy(t ->
                t.getFactory() + "#" + t.getSkuId() + "#" + t.getLotno()));
        Map<String, List<SaleReportInvInfo>> freezeCollect = freezeGroupInfo.stream().collect(Collectors.groupingBy(t ->
                t.getFactory() + "#" + t.getSkuId() + "#" + t.getLotno()));
        //查询返回信息
        List<SaleInvReportReponse> datas = saleInvReportMapper.selectAll(search);
        try {
            for (SaleInvReportReponse data : datas) {
                List<SoGroupInfo> soInfos = soCollect.get(data.getSoNo() + "#" + data.getSoItem());
                BigDecimal totalInvQtys=BigDecimal.ZERO;
                BigDecimal totalFreezeInvQtys=BigDecimal.ZERO;
                if (!CollectionUtil.isEmpty(soInfos)){
                    for (SoGroupInfo soInfo : soInfos) {
                        List<SaleReportInvInfo> invInfoList = invCollect.get(
                                data.getFactory() + "#" + data.getSkuId() + "#" + soInfo.getLotno());
                        List<SaleReportInvInfo> freezeList = freezeCollect.get(
                                data.getFactory() + "#" + data.getSkuId() + "#" + soInfo.getLotno());
                        if (!CollectionUtil.isEmpty(invInfoList)){
                            BigDecimal tempInv;
                            for (SaleReportInvInfo inv : invInfoList) {
                                if (inv!=null){
                                    tempInv = inv.getQtys();
                                    if (tempInv!=null) totalInvQtys=totalInvQtys.add(tempInv);
                                }
                            }
                        }
                        if (!CollectionUtil.isEmpty(freezeList)){
                            BigDecimal tempFreeze;
                            for (SaleReportInvInfo freeze : freezeList) {
                                if (freeze!=null){
                                    tempFreeze=freeze.getQtys();
                                    if (tempFreeze!=null)
                                    totalFreezeInvQtys=totalFreezeInvQtys.add(tempFreeze);
                                }
                            }
                        }
                    }
                }
                data.setInvQtys(totalInvQtys);
                data.setFreezeInvQtys(totalFreezeInvQtys);

                //根据库龄设置库龄分类
                if (data.getInvAge()!=null){
                    if (data.getInvAge()<=30L){
                        data.setInvAgeType("常规库存");
                    }else if (data.getInvAge()<=60L){
                        data.setInvAgeType("预警库存");
                    }else {
                        data.setInvAgeType("呆滞库存");
                    }
                }else {
                    data.setInvAgeType("常规库存");
                }

            }


        }catch (Exception e){
            e.printStackTrace();
        }
        return datas;
    }


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public PagerInfo<List<SaleInvReportReponse>> searchSaleInvReportNew(
            SaleInvReportSearchRequest search, Pager<?> pager) {
        Page<SaleInvReportReponse> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        List<SaleInvReportReponse> datas = saleInvReportMapper.selectAllNew(search);
        PagerInfo<List<SaleInvReportReponse>> pagerInfo = new PagerInfo<>();
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(datas);

        return pagerInfo;
    }

    @Transactional
    public void exportSaleInvReportNew(
            SaleInvReportSearchRequest search,
            HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception{
        ServletOutputStream out = null;
        XSSFWorkbook workbook = null;
        try {
            List<SaleInvReportReponse> datas = saleInvReportMapper.selectAllNew(search);
            List<ExcelExportConfig> configs = new ArrayList<>();
            configs.add(new ExcelExportConfig("组织", "factory", 120));
            configs.add(new ExcelExportConfig("销售订单号", "soNo", 120));
            configs.add(new ExcelExportConfig("销售订单行号", "soItem", 120));
            configs.add(new ExcelExportConfig("订单号", "po", 120));
            configs.add(new ExcelExportConfig("物料编码", "skuCode", 120));
            configs.add(new ExcelExportConfig("物料描述", "descCn", 120));
            configs.add(new ExcelExportConfig("原型机", "modelMechanic", 120));
            configs.add(new ExcelExportConfig("部门名称", "businessDept", 120));
            configs.add(new ExcelExportConfig("科室名称", "businessSection", 120));
            configs.add(new ExcelExportConfig("客户编码", "customerCode", 120));
            configs.add(new ExcelExportConfig("客户名称", "customerName", 120));
            configs.add(new ExcelExportConfig("品牌", "brand", 120));
            configs.add(new ExcelExportConfig("国家", "country", 120));
            configs.add(new ExcelExportConfig("业务员", "businessMan", 120));
            configs.add(new ExcelExportConfig("订单类型", "soType", 120));
            configs.add(new ExcelExportConfig("机型类型", "modeType", 120));
            configs.add(new ExcelExportConfig("付款方式", "payMode", 120));
            configs.add(new ExcelExportConfig("定/变频", "frequeType", 120));
            configs.add(new ExcelExportConfig("是否窗机", "isWindow", 120));
            configs.add(new ExcelExportConfig("是否散件", "isCskd", 120));
            configs.add(new ExcelExportConfig("最后入库时间", "lastStockInDate", 120));
            configs.add(new ExcelExportConfig("开工时间", "planDate", 120));
            configs.add(new ExcelExportConfig("订单数量", "qty", 120));
            configs.add(new ExcelExportConfig("未结量", "noCountQty", 120));
            configs.add(new ExcelExportConfig("库存量", "invQtys", 120));
            configs.add(new ExcelExportConfig("封位货位库存", "freezeInvQtys", 120));
            configs.add(new ExcelExportConfig("库龄", "invAge", 120));
            configs.add(new ExcelExportConfig("库龄分类", "invAgeType", 120));

            workbook = HttpExcel.newListToExcel(datas, configs);
            String userAgent = servletRequest.getHeader("USER-AGENT");
            String fileName = "整机外销库存报表";
            if (userAgent.contains("Mozilla")) {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } else {
                fileName = URLEncoder.encode(fileName, "utf8");
            }
            servletResponse.setContentType("application/octet-stream");
            servletResponse.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".xlsx");
            servletResponse.flushBuffer();
            out = servletResponse.getOutputStream();
            workbook.write(out);
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (out != null) {
                out.flush();
                out.close();
            }
            if(workbook != null) {
                workbook.close();
            }
        }
    }


}
